﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using StyleMVVM.Configuration;
using StyleMVVM.Logging;

#if NETFX_CORE
using Windows.Foundation;
#endif

namespace StyleMVVM.DependencyInjection.Conditions
{
	public sealed class WhenConfigValue : IExportCondition
	{
		private static string supplemental = typeof(WhenConfigValue).FullName;
		private bool? answer;
		private bool cache;
		private string configName;
		private object configValue;

		public WhenConfigValue(string configName, object configValue, bool cache)
		{
			this.configName = configName;
			this.configValue = configValue;
			this.cache = cache;
		}

		public bool ConditionMeet(IDependencyInjectionContainer container,
										  IInjectionContext injectionContext,
										  IExportStrategy exportStrategy)
		{
			if (answer.HasValue)
			{
				return answer.Value;
			}

			bool returnValue = false;

			IConfigurationService configurationService =
				container.LocateByType(typeof(IConfigurationService)) as IConfigurationService;

			if (configurationService != null)
			{
#if NETFX_CORE
				IAsyncOperation<object> testValue = configurationService.GetValue(configName, configValue.GetType(), null);
				Task<object> configTask = testValue.AsTask();
#else
				Task<object> configTask = configurationService.GetValue(configName, configValue.GetType(), null);
#endif

				configTask.Wait(100);

				if (configTask.IsCompleted)
				{
					if (Equals(configValue, configTask.Result))
					{
						returnValue = true;
					}
				}
				else if (configTask.IsFaulted)
				{
					Logger.Error("Exception thrown while fetching config value: " + configName, supplemental, configTask.Exception);
				}
				else
				{
					configTask.ContinueWith(x =>
					{
						if (x.Exception != null)
						{
							Logger.Error("Exception thrown while fetching config value: " + configName, supplemental, x.Exception);
						}
						else
						{
							Logger.Warn("Took to long to fetch config value: " + configName,supplemental);
						}
					});
				}
			}

			if (cache)
			{
				answer = returnValue;
			}

			return returnValue;
		}
	}
}
